#include <iostream>
#include <cstring>
#include "49String.hpp"

// 这里一定要初始化静态变量,声明的时候不能这样做
int String::str_count = 0;

String::String(const char *s)
{
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    str_count++;
}

String::String()
{
    len = 4;
    str = new char[1];
    str = nullptr; // default string 默认为 \0
    str_count++;
}

// 复制构造函数,  函数传参,复制
String::String(const String &s)
{
    len = s.len;
    str = new char[len + 1];
    strcpy(str, s.str);
    str_count++;
}

String::~String()
{
    delete[] str;
    str_count--;
}

// sb = sb1 = sb2;      sb为String类型,将会调用operator=()函数
String &String::operator=(const String &st)
{
    // 如果比较的是同一块内存
    if (this == &st)
        return *this;
    // 不同内存,则释放内存,将内存重新分配,并赋值
    delete[] str; // 如果没有释放,将会失去唯一的指针,这个内存将会失去控制,造成内存溢出
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);
    return *this;
}

String &String::operator=(const char *s)
{
    delete[] str;
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    return *this;
}

int String::length() const
{
    return len;
}

// 通过cin输入
istream &operator>>(istream &is, String &st)
{
    // 创建临时存储
    char temp[String::CIN_LIMIT];

    is.get(temp, String::CIN_LIMIT);
    //        inline std::istream &std::istream::get(char *__s, std::streamsize __n)
    //        Simple multiple-character extraction.
    //        参数:
    //        __s – Pointer to an array.
    //        __n – Maximum number of characters to store in s.

    // 如果有输入错误,或者换行 cin将为false;
    if (is)
        st = temp;
    while (is && is.get() != '\n')
        continue;
    return is;
}

// 通过cout输出
ostream &operator<<(ostream &os, const String &st)
{
    os << st.str;
    return os;
}

bool operator==(const String &str1, const String &str2)
{
    return (std::strcmp(str1.str, str2.str) == 0);
}

// 这里有bug,变成大于号会直接死
bool operator<(const String &str1, const String &str2)
{
    return (std::strcmp(str1.str, str2.str) < 0);
}
// 这里有bug,变成小于号会直接死
bool operator>(const String &str1, const String &str2)
{
    // 调用operator>()
    return str2 < str1;
}

char &String::operator[](int i)
{
    return str[i];
}

// read-only
const char &String::operator[](int i) const
{
    return str[i];
}

